/* 
 * Author: anand
 * 
 */

#include "path_util.h"

const char * path_util::get_working_dir()
{
	static char dir[256];
	return getcwd(dir,256);
}
bool path_util::is_valid_path(const char *path)
{
	struct stat buff;
	if(stat(path,&buff))
		return false;
	else
		return true;
}

bool path_util::is_relative_path(const char * path)
{
	std::string cwd = get_working_dir();
	cwd.append("/");
	cwd.append(path);
	return is_valid_path(cwd.c_str());
}
const char* path_util::get_absolute_path(const char* path){
	static char rp[256];
    char *rpc = rp;
    if(is_relative_path(path))
	{
     	std::string cwd = get_working_dir();
	    cwd.append("/");
	    cwd.append(path);
		return get_normalized_path(cwd.c_str());
	}
	else
	{
		return get_normalized_path(path);
	}
}
const char* path_util::get_normalized_path(const char * abspath)
{
	/*
	* Assume we have a valid absolute path
	* A normalized path is an absolute path ending in file name
    */

	static std::string normalized;
	normalized = abspath;
	std::string::reverse_iterator p = normalized.rbegin();
	int trimcount = 0;
	bool updated = true;
	//remove ending /
	while(p != normalized.rend() && updated)
	{
		if(!updated && (*p == '/' || *p == '\\'))
		{
			trimcount++;
			updated = true;
		}
		p++;
	}
	normalized.resize(normalized.size()-trimcount);

	//convert \ to / needed for windows only...
	if(normalized[1] == '\\' || normalized[1] == ':') //UNC and normal drive letter
	{
		updated = true;
		while(updated)
		{
			updated = false;
			int bs = normalized.rfind("\\");
			if(bs > 1)
			{
				updated = true;
				normalized.replace(bs,1,"/");
			}
		}
	}
	updated = true;
	while(updated)
	{
		updated = false;
		int sd = normalized.rfind("/./");
		if(sd != std::string::npos)
		{
			updated = true;
			normalized.replace(sd,3,"/");
		}
	}

	updated = true;
	while(updated)
	{
		updated = false;
		int dbs = normalized.find("//");
		if(dbs != std::string::npos)
		{
			updated = true;
			normalized.replace(dbs,2,"/");
		}
	}

	return normalized.c_str();
}

std::string path_util::convert_to_string(double integer){
	char rval[125]; // magic number  ??? :(
	sprintf(rval,"%f",integer);
	return std::string(rval);
}
std::string path_util::get_file_name(std::string path_){
	std::string normalizedPath = get_absolute_path(path_.c_str());
	int pos = normalizedPath.rfind("/");
	if(pos != std::string::npos)
		return normalizedPath.replace(0,pos+1,"");
	else
		return std::string();
}

char * path_util::get_home_dir()
{
	char * hDrive = strdup(getenv("HOMEDRIVE"));
	char * hPath = strdup(getenv("HOMEPATH"));

	static char *path = new char[256];
	*path = '\0';
	sprintf(path,"%s%s\\",hDrive,hPath);

	return path;
}

std::string path_util::get_folder_path(std::string path_)
{
	std::string normalizedFolderPath = get_absolute_path(path_.c_str());
	std::string folderPath = normalizedFolderPath.substr(0,normalizedFolderPath.rfind("/")+1); //hmmm, include the / in the string so can save it directly
	return folderPath;
}
